/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controladores;

import Controladores.exceptions.NonexistentEntityException;
import Controladores.exceptions.PreexistingEntityException;
import entidades.Owner;
import entidades.Person;
import entidades.Person_;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import entidades.Pet;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.ParameterExpression;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

/**
 *
 * @author Gatoper
 */
public class OwnerJpaController implements Serializable {

    public OwnerJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Owner owner) throws PreexistingEntityException, Exception {
        if (owner.getPet() == null) {
            owner.setPet(new ArrayList<Pet>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            List<Pet> attachedPet = new ArrayList<Pet>();
            for (Pet petPetToAttach : owner.getPet()) {
                petPetToAttach = em.getReference(petPetToAttach.getClass(), petPetToAttach.getName());
                attachedPet.add(petPetToAttach);
            }
            owner.setPet(attachedPet);
            em.persist(owner);
            for (Pet petPet : owner.getPet()) {
                //petPet.getOwner().add(owner);
                petPet = em.merge(petPet);
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findOwner(owner.getName()) != null) {
                throw new PreexistingEntityException("Owner " + owner + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Owner owner) throws NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Owner persistentOwner = em.find(Owner.class, owner.getName());
            List<Pet> petOld = persistentOwner.getPet();
            List<Pet> petNew = owner.getPet();
            List<Pet> attachedPetNew = new ArrayList<Pet>();
            for (Pet petNewPetToAttach : petNew) {
                petNewPetToAttach = em.getReference(petNewPetToAttach.getClass(), petNewPetToAttach.getName());
                attachedPetNew.add(petNewPetToAttach);
            }
            petNew = attachedPetNew;
            owner.setPet(petNew);
            owner = em.merge(owner);
            for (Pet petOldPet : petOld) {
                if (!petNew.contains(petOldPet)) {
                    // petOldPet.getOwner().remove(owner);
                    petOldPet = em.merge(petOldPet);
                }
            }
            for (Pet petNewPet : petNew) {
                if (!petOld.contains(petNewPet)) {
                    // petNewPet.getOwner().add(owner);
                    petNewPet = em.merge(petNewPet);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                String id = owner.getName();
                if (findOwner(id) == null) {
                    throw new NonexistentEntityException("The owner with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(String id) throws NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Owner owner;
            try {
                owner = em.getReference(Owner.class, id);
                owner.getName();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The owner with id " + id + " no longer exists.", enfe);
            }
            List<Pet> pet = owner.getPet();
            for (Pet petPet : pet) {
                //petPet.getOwner().remove(owner);
                petPet = em.merge(petPet);
            }
            em.remove(owner);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Owner> findOwnerEntities() {
        return findOwnerEntities(true, -1, -1);
    }

    public List<Owner> findOwnerEntities(int maxResults, int firstResult) {
        return findOwnerEntities(false, maxResults, firstResult);
    }

    private List<Owner> findOwnerEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Owner.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Owner findOwner(String id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Owner.class, id);
        } finally {
            em.close();
        }
    }

    public List<Owner> findOwnerByProp(String prop, String c) {
        EntityManager em = getEntityManager();
        try {
            CriteriaBuilder cb = em.getCriteriaBuilder();
            CriteriaQuery<Owner> cq = cb.createQuery(Owner.class);
            Root<Owner> owner = cq.from(Owner.class);
            cq.select(owner).where(cb.like(owner.<String>get(prop), "%" + c + "%"));
            Query q = em.createQuery(cq);
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public TableModel findPetsAndPrices(Owner o) {        
        List<Pet> mascotas = o.getPet();
        PetJpaController pjc=new PetJpaController(emf);
        Object[][] datosPet= new Object[mascotas.size()][2];
        for (int i = 0; i < mascotas.size(); i++) {
            datosPet[i][0]=mascotas.get(i).getName();
            
            datosPet[i][1]=pjc.findPetPrice(mascotas.get(i).getName());
        }
        String[] tituloPet = new String[]{"name", "price"};
        return new DefaultTableModel(datosPet, tituloPet);
    }

    public List<Owner> findOwnernm(String c) {
        return findOwnerByProp("name", c);
        /*EntityManager em = getEntityManager();
         try {
         String sql="select * from hpvas.owner join hpvas.person on (owner.name=person.name) where owner.name like '%" + c + "%';";
         Query query = em.createNativeQuery(sql);
         return query.getResultList();
         } finally {
         em.close();
         }*/
    }

    public List<Owner> findOwnerBySSN(String c) {
        EntityManager em = getEntityManager();
        try {
            String sql = "select owner.name from hpvas.owner join hpvas.person on (owner.name=person.name) where person.SSN like '%" + c + "%';";
            Query query = em.createNativeQuery(sql);
            List<String> a = query.getResultList();
            List<Owner> retorno = new Vector();
            for (int i = 0; i < a.size(); i++) {
                retorno.add(findOwner(a.get(i)));
            }
            return retorno;
        } finally {
            em.close();
        }
    }

    public int getOwnerCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Owner> rt = cq.from(Owner.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
}
